﻿using UnityEngine;
using UnityEditor;
using System;

namespace WentStateMachine
{
    [Serializable]
    public class WentStateMachineBehaviour : StateMachineBehaviour
    {
        [SerializeField] public StateBehaviour StateBehaviour;
        [HideInInspector] public string selectedName;

        public override void OnStateEnter(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
        {
            if (StateBehaviour == null)
            {
                Debug.LogWarning("null");
                return;
            }
            StateBehaviour.OnWentStateEnter(new ControllerForAnimator(animator), new StateInfoForAnimator(stateInfo), layerIndex);
        }

        public override void OnStateUpdate(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
        {
            if (StateBehaviour == null)
            {
                Debug.LogWarning("null");
                return;
            }
            StateBehaviour.OnWentStateUpdate(new ControllerForAnimator(animator), new StateInfoForAnimator(stateInfo), layerIndex);
        }

        public override void OnStateExit(Animator animator, AnimatorStateInfo stateInfo, int layerIndex)
        {
            if (StateBehaviour == null)
            {
                Debug.LogWarning("null");
                return;
            }
            StateBehaviour.OnWentStateExit(new ControllerForAnimator(animator), new StateInfoForAnimator(stateInfo), layerIndex);
        }
    }

    [CustomEditor(typeof(WentStateMachineBehaviour))]
    public class WentStateMachineBehaviourEditor : Editor
    {
        WentStateMachineBehaviour behaviour;
        GUIContent[] listContent;
        string[] names;
        int selectedIndex;

        private void OnEnable()
        {
            behaviour = target as WentStateMachineBehaviour;
            names = FindStateHelper.Names;
            listContent = new GUIContent[names.Length];
            for (var i = 0; i < names.Length; i++)
            {
                listContent[i] = new GUIContent(names[i]);
            }

            if (behaviour.StateBehaviour == null && names.Length > 0)
            {
                if(string.IsNullOrEmpty(behaviour.selectedName))
                    behaviour.selectedName = names[0];
                initNewState(FindStateHelper.FindTypeByName(behaviour.selectedName));
            }
            selectedIndex = findNameIndex(names, behaviour.selectedName);
        }

        public override void OnInspectorGUI()
        {
            base.OnInspectorGUI();
            EditorGUILayout.BeginVertical();
            var select = EditorGUILayout.Popup(selectedIndex, listContent);
            if(select != selectedIndex)
            {
                initNewState(FindStateHelper.FindTypeByName(names[select]));
                behaviour.selectedName = names[select];
                selectedIndex = select;
            }

            if (behaviour.StateBehaviour != null)
                behaviour.StateBehaviour.OnStateGUI();
            EditorGUILayout.EndVertical();
        }

        int findNameIndex(string[] names, string target)
        {
            for(int i = 0; i < names.Length; i++)
            {
                if (names[i] == target)
                    return i;
            }
            return 0;
        }

        void initNewState(Type type)
        {
            if (behaviour.StateBehaviour != null)
                AssetDatabase.RemoveObjectFromAsset(behaviour.StateBehaviour);
            behaviour.StateBehaviour = (StateBehaviour)CreateInstance(type);
            behaviour.StateBehaviour.name = $"({type.FullName})";
            AssetDatabase.AddObjectToAsset(behaviour.StateBehaviour, behaviour);
            
        }
    }

    public struct Group
    {
        public string GroupName;
        public Group[] Groups;
        public Item[] Items;
    }

    public struct Item
    {
        public string Name;
        public Type Type;
    }
}
